//
//  virtual_exercise.hpp
//  learnC++
//
//  Created by liuzhibing on 2018/6/19.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#ifndef virtual_exercise_hpp
#define virtual_exercise_hpp

#include <stdio.h>
#include <iostream>

class Point2 {
private:
    int m_x;
    int m_y;
    int m_z;
    
public:
    Point2(int x,int y,int z):m_x(x),m_y(y),m_z(z){
        
    }
    
    friend std::ostream &operator<<(std::ostream &out,const Point2 &p);
    
};

class Shaper {
    
public:
    
    virtual std::ostream &print(std::ostream &out) const = 0;
    
    friend std::ostream &operator<<(std::ostream &out,const Shaper &s){
        
        return s.print(out);
    }
    
    virtual ~Shaper(){}
};

class Triangle : public Shaper {
private:
    Point2 m_p1;
    Point2 m_p2;
    Point2 m_p3;
    
public:
    Triangle(const Point2 &p1,const Point2 &p2,const Point2 &p3):m_p1(p1),m_p2(p2),m_p3(p3){
        
    }
    
    virtual std::ostream &print(std::ostream &out) const{
        out << "Triangle(" << m_p1 << ", " << m_p2 << ", " << m_p3 << ")";
        return out;
    }
    
};

class Circle : public Shaper {
    
private:
    Point2 m_center;
    int m_radius;
    
public:
    Circle(const Point2 &center,int radius):m_center(center),m_radius(radius){
        
    }
    
    virtual std::ostream &print(std::ostream &out) const{
        out << "Circle(" << m_center << ", " << m_radius << ")";
        return out;
    }
    
};

/*
 
 std::vector<Shaper *> v;
 
 Triangle *tp = new Triangle(Point2(9, 0, 0),Point2(1, 7, 8),Point2(2, 2, 2));
 Circle *cp = new Circle(Point2(3, 8, 3),3);
 
 v.push_back(tp);
 v.push_back(cp);
 
 for(auto &element : v){
 std::cout << *element;
 }
 
 */

/*
 std::bind用来将可调用对象与其参数一起进行绑定。绑定后可以使用std::function进行保存，并在需要的时候调用
 
 ClassA a;
 std::function<void(int,int)> fr = std::bind(&A::output,&a,std::placeholdrs::_1,std::placeholders::_2);
 
 fr(1,2);
 
 绑定成员变量
 stdfunction<int &(void)> fr2 = std::bind(&A::i_,&a);
 fr2() = 100;//对成员变量赋值
 */

#endif /* virtual_exercise_hpp */
